package com.zq.user.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zq.common.exception.ResultException;
import com.zq.common.util.JwtUtil;
import com.zq.minio.service.MinioService;
import com.zq.user.dao.dto.LoginDto;
import com.zq.user.dao.entity.UserInfo;
import com.zq.user.dao.entity.Users;
import com.zq.user.mapper.UsersMapper;
import com.zq.user.saconfig.UserStpUtil;
import com.zq.user.service.IUsersService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户表，用于存储系统用户信息 服务实现类
 * </p>
 *
 * @author 张乔
 * @since 2025-04-27
 */
@Service
@Slf4j
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements IUsersService {

    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    //用户登录方法
    @Override
    public String login(LoginDto loginDto) {
        log.info("loginDto:{}", loginDto);
//        先检验验证码
        String codeRedis = redisTemplate.opsForValue().get(loginDto.getCodeKey());
        log.info("codeRedis:{}", codeRedis);

        if (codeRedis==null){
            throw new ResultException(555,"验证码不存在");
        }
        if (!codeRedis.equals(loginDto.getCodeValue().toLowerCase())) {
            throw new ResultException(555, "验证码错误");
        }
//        验证码正确，删除redis中的验证码
        redisTemplate.delete(loginDto.getCodeKey());
//        用户登录
        Users users = this.getOne(new LambdaQueryWrapper<Users>().eq(Users::getUsername, loginDto.getUsername()));
        if(users==null){
            throw new ResultException(555,"用户不存在");
        }

        String md5 = SaSecureUtil.md5(loginDto.getPassword());
        if (!md5.equals(users.getPassword())){
            throw new ResultException(555,"密码错误");
        }
        //根据用户id登录，第1步，先登录上
        UserStpUtil.login(users.getId());
        // 第2步，获取 Token  相关参数
        SaTokenInfo tokenInfo = UserStpUtil.getTokenInfo();
        // 第3步，返回给前端
        return tokenInfo.getTokenValue();
    }

    @Resource
    private JwtUtil jwtUtil;


//    根据请求头中的token，获取用户信息
    @Override

    public Users getUserInfo(String userToken) {
        String redisUser = redisTemplate.opsForValue().get("redisUser"+userToken);
        if(StringUtils.hasText(redisUser)){
            return JSON.parseObject(redisUser, Users.class);
        }

        Integer userId = jwtUtil.getUsernameFromToken(userToken);
        Users users = this.getById(userId);

if (users==null){
    throw new ResultException(500,"用户不存在");
}
//        将用户信息放入redis中，并设置过期时间
redisTemplate.opsForValue().set("redisUser"+userToken, JSON.toJSONString(users),60, TimeUnit.MINUTES);

        return users;
    }

    //注册方法
    @Override
    public void register(Users users) {
        Users one = this.getOne(new LambdaQueryWrapper<Users>().eq(users.getUsername()!=null,Users::getUsername, users.getUsername()));

        if (one!=null){
            throw new ResultException(500,"用户名已存在");
        }
//        密码加密
        users.setPassword(SaSecureUtil.md5(users.getPassword()));
        this.save(users);
    }

    @Resource
    private MinioService minioService;


//    修改头像
@Override
public String updateAvatar(MultipartFile file, String token) {
    String file1= minioService.uploadFile(file);
    Integer userId = jwtUtil.getUsernameFromToken(token);
    Users user = this.getById(userId);
    user.setAvatar(file1);
    this.updateById(user);
    log.info("修改头像成功");
    //           删除redis中的用户信息
    redisTemplate.delete("redisUser"+token);
    return file1;
}

//退出登录
    @Override
    public void logout(String userToken) {
        Integer userId = jwtUtil.getUsernameFromToken(userToken);
        if(userId==null){
            throw new ResultException(555,"用户不存在");
        }
        //退出登陆时，sa-token会自动删除redis中的数据
    UserStpUtil.logout(userId);
        log.info("退出登录成功");

    }

//    修改用户信息
    @Override
    public void updateUserInfo(Users users, String token) {
        Integer userId = jwtUtil.getUsernameFromToken(token);
//        保证业务的健壮性，如果用户不存在，则抛出异常
        if(userId==null){
            throw new ResultException(555,"用户不存在");
        }
        Users redisUser = this.getById(userId);
        if (redisUser==null){
            throw new ResultException(555,"用户不存在");
        }
        if (users.getUsername()==null|| users.getUsername().isEmpty()){
        throw new ResultException(500,"用户名不能为空");
        }
        log.info("redisUser:{}", redisUser);
        log.info("users:{}", users);
//        如果用户修改了它的用户名，传入的用户名和redis中的用户名不一致。
        if (!redisUser.getUsername().equals(users.getUsername())){
            Users user2 = this.getOne(new LambdaQueryWrapper<Users>().
                    eq(Users::getUsername,users.getUsername()));
//            如果数据库中已经存在了该用户名，则抛出异常
            if (user2!=null){
                throw new ResultException(555,"用户名已存在，请你再换一个");
            }
//            如果用户修改了密码，则对密码进行加密
            if(StringUtils.hasText(users.getPassword())){
                String md5 = SaSecureUtil.md5(users.getPassword());
                users.setPassword(md5);
            }
            log.info("users------------>"+users);
            users.setId(userId);
            this.updateById(users);
//           删除redis中的用户信息
           redisTemplate.delete("redisUser"+token);
            log.info("修改用户信息成功");
            return;
        }

//        用户没有修改它的用户名
//            如果用户修改了密码，则对密码进行加密
        if(StringUtils.hasText(users.getPassword())){
            String md5 = SaSecureUtil.md5(users.getPassword());
            users.setPassword(md5);
        }

        users.setId(userId);
        this.updateById(users);
        log.info("修改用户信息成功");
//           删除redis中的用户信息
        redisTemplate.delete("redisUser"+token);

    }




}
